package scatter.wxmp.rest.notify;

import cn.hutool.core.util.StrUtil;
import cn.hutool.json.JSONUtil;
import lombok.extern.slf4j.Slf4j;
import me.chanjar.weixin.common.error.WxErrorException;
import me.chanjar.weixin.mp.api.WxMpService;
import me.chanjar.weixin.mp.bean.template.WxMpTemplateData;
import me.chanjar.weixin.mp.bean.template.WxMpTemplateMessage;
import org.springframework.beans.factory.annotation.Autowired;
import scatter.common.rest.exception.BusinessException;
import scatter.common.rest.notify.AbstractNotifyListener;
import scatter.common.rest.notify.NotifyParam;
import scatter.common.rest.tools.InterfaceTool;

import java.util.List;
import java.util.Map;

/**
 * <p>
 * 微信模板消息通知实现
 * </p>
 *
 * @author yangwei
 * @since 2021-09-02 19:45
 */
@Slf4j
public class DefaultWxMpTemplateNotifyListenerImpl extends AbstractNotifyListener implements InterfaceTool {

	public static String APPID_KEY = "wx_mp_appId_key";
	public static String TEMPLATE_ID_KEY = "wx_mp_template_id_key";
	public static String DATA_KEY = "wx_mp_data_key";
	public static String MINI_PROGRAM_KEY = "wx_mp_mini_program_key";

	@Autowired
	private IWxMpNotifyAppIdResolver iWxMpNotifyAppIdResolver;
	@Autowired
	private WxMpService wxMpService;

	@Override
	protected String supportType() {
		return NotifyParam.Type.wxmpTemplate.name();
	}

	@Override
	public void doNotify(NotifyParam notifyParam) {
		String appId = resolveAppId(notifyParam.getExt());
		if (isStrEmpty(appId)) {
			appId = iWxMpNotifyAppIdResolver.resolve(notifyParam);
		}
		if (isStrEmpty(appId)) {
			log.warn("微信公众号通知未获取到 appId，将不会发送通知，通知参数={}",toJsonStr(notifyParam));
			return;
		}

		boolean switchover = wxMpService.switchover(appId);
		if (!switchover) {
			log.warn("微信公众号通知切换 appId 返回false，将不会发送通知，appId={},通知参数={}",appId,toJsonStr(notifyParam));
			return;
		}
		WxMpTemplateMessage wxMpTemplateMessage = new WxMpTemplateMessage();
		String templateId = (String) notifyParam.getExt().get(TEMPLATE_ID_KEY);
		if (isStrEmpty(templateId)) {
			throw new BusinessException(StrUtil.format("templateId 没有值请以key={}设置在额外参数中",TEMPLATE_ID_KEY));
		}
		wxMpTemplateMessage.setTemplateId(templateId);
		wxMpTemplateMessage.setUrl(notifyParam.getLinkUrl());
		Object data = notifyParam.getExt().get(DATA_KEY);
		if (data != null) {
			throw new BusinessException(StrUtil.format("data 没有值请以key={}设置在额外参数中,支持的类型为List<WxMpTemplateData>或其json字符串",DATA_KEY));
		}
		List<WxMpTemplateData> dataList = null;
		if(data instanceof String){
			dataList = JSONUtil.toList((String) data,WxMpTemplateData.class);
		}else if(data instanceof List){
			dataList = (List<WxMpTemplateData> )data;
		}else {
			throw new BusinessException("data 类型不正确,支持的类型为List<WxMpTemplateData>或其json字符串");
		}
		wxMpTemplateMessage.setData(dataList);

		// 小程序参数
		Object miniPrograpmData = notifyParam.getExt().get(MINI_PROGRAM_KEY);
		if (miniPrograpmData != null) {
			WxMpTemplateMessage.MiniProgram miniProgram = null;
			if(miniPrograpmData instanceof WxMpTemplateMessage.MiniProgram){
				miniProgram = ((WxMpTemplateMessage.MiniProgram) miniPrograpmData);
			}else if(miniPrograpmData instanceof String){
				miniProgram = JSONUtil.toBean(((String) miniPrograpmData),WxMpTemplateMessage.MiniProgram.class);
			}else {
				throw new BusinessException("MiniProgram 类型不正确,支持的类型为WxMpTemplateMessage.MiniProgram或其json字符串");
			}
			wxMpTemplateMessage.setMiniProgram(miniProgram);
		}

		try {
			for (String openId : notifyParam.getToUser()) {
				// 这里只能设置一个用户
				wxMpTemplateMessage.setToUser(openId);
				wxMpService.getTemplateMsgService().sendTemplateMsg(wxMpTemplateMessage);
			}
		} catch (WxErrorException e) {
			throw new RuntimeException(e);
		}

	}

	/**
	 * 获取 appId
	 * @param ext
	 * @return
	 */
	private String resolveAppId(Map<String,Object> ext){
		if (ext == null) {
			return null;
		}
		return (String) ext.get(APPID_KEY);
	}
}
